"""
Response models for CodeMCP API.

Defines Pydantic models for API responses.
"""

from typing import Dict, Any, List, Optional, Union
from pydantic import BaseModel, Field
from datetime import datetime
from enum import Enum


class ResponseStatus(str, Enum):
    """Response status options."""
    SUCCESS = "success"
    ERROR = "error"
    PARTIAL = "partial"
    PENDING = "pending"


class HealthStatus(str, Enum):
    """Health status options."""
    HEALTHY = "healthy"
    UNHEALTHY = "unhealthy"
    WARNING = "warning"
    UNKNOWN = "unknown"


class BaseResponse(BaseModel):
    """Base response model."""
    status: ResponseStatus = Field(..., description="Response status")
    timestamp: datetime = Field(default_factory=datetime.utcnow, description="Response timestamp")
    request_id: Optional[str] = Field(None, description="Request identifier")
    processing_time: Optional[float] = Field(None, description="Processing time in seconds")


class ErrorResponse(BaseResponse):
    """Error response model."""
    status: ResponseStatus = ResponseStatus.ERROR
    error_code: str = Field(..., description="Error code")
    message: str = Field(..., description="Error message")
    details: Optional[Dict[str, Any]] = Field(None, description="Error details")
    context: Optional[Dict[str, Any]] = Field(None, description="Error context")


class CallTreeNodeResponse(BaseModel):
    """Response model for call tree nodes."""
    id: str = Field(..., description="Node identifier")
    name: str = Field(..., description="Node name")
    file_path: str = Field(..., description="File path")
    line_number: int = Field(..., description="Line number")
    language: str = Field(..., description="Programming language")
    node_type: str = Field(..., description="Node type (function, method, class, etc.)")
    signature: Optional[str] = Field(None, description="Function signature")
    documentation: Optional[str] = Field(None, description="Documentation string")
    short_description: Optional[str] = Field(None, description="Short description")
    llm_explanation: Optional[str] = Field(None, description="LLM-generated explanation")
    semantic_tags: List[str] = Field(default_factory=list, description="Semantic tags")
    complexity_score: float = Field(0.0, description="Complexity score")
    call_frequency: int = Field(0, description="Call frequency")
    caller_count: int = Field(0, description="Number of callers")
    callee_count: int = Field(0, description="Number of callees")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")


class CallTreeResponse(BaseModel):
    """Response model for call trees."""
    root_node: Optional[CallTreeNodeResponse] = Field(None, description="Root node")
    nodes: Dict[str, CallTreeNodeResponse] = Field(default_factory=dict, description="All nodes")
    edges: List[Dict[str, str]] = Field(default_factory=list, description="Call relationships")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="Tree metadata")
    
    class Config:
        schema_extra = {
            "example": {
                "root_node": {
                    "id": "main_node",
                    "name": "main",
                    "file_path": "/src/main.py",
                    "line_number": 10,
                    "language": "python",
                    "node_type": "function"
                },
                "nodes": {},
                "edges": [
                    {"from": "main_node", "to": "helper_node", "type": "calls"}
                ],
                "metadata": {
                    "total_nodes": 5,
                    "max_depth": 3,
                    "analysis_type": "automatic"
                }
            }
        }


class AnalysisResponse(BaseResponse):
    """Response model for code analysis."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    call_tree: CallTreeResponse = Field(..., description="Generated call tree")
    analysis_metadata: Dict[str, Any] = Field(default_factory=dict, description="Analysis metadata")
    session_id: Optional[str] = Field(None, description="Session identifier")
    language_detected: Optional[str] = Field(None, description="Detected language")
    file_info: Dict[str, Any] = Field(default_factory=dict, description="File information")
    dependencies: List[Dict[str, Any]] = Field(default_factory=list, description="Dependencies found")
    
    class Config:
        schema_extra = {
            "example": {
                "status": "success",
                "call_tree": {
                    "root_node": {"name": "main", "file_path": "/src/main.py"},
                    "nodes": {},
                    "metadata": {"total_nodes": 10}
                },
                "analysis_metadata": {
                    "mode": "automatic",
                    "max_depth_reached": 5,
                    "cross_language_calls": 2
                },
                "session_id": "session_123",
                "language_detected": "python"
            }
        }


class ExplorationResponse(BaseResponse):
    """Response model for exploration actions."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    action_result: Dict[str, Any] = Field(..., description="Action result")
    current_node: CallTreeNodeResponse = Field(..., description="Current node")
    available_actions: List[str] = Field(default_factory=list, description="Available actions")
    candidate_nodes: List[CallTreeNodeResponse] = Field(default_factory=list, description="Candidate nodes")
    navigation_stack: List[str] = Field(default_factory=list, description="Navigation stack")
    session_info: Dict[str, Any] = Field(default_factory=dict, description="Session information")


class FunctionInfoResponse(BaseResponse):
    """Response model for function information."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    function_info: CallTreeNodeResponse = Field(..., description="Function information")
    callers: List[CallTreeNodeResponse] = Field(default_factory=list, description="Caller functions")
    callees: List[CallTreeNodeResponse] = Field(default_factory=list, description="Callee functions")
    source_code: Optional[str] = Field(None, description="Source code")
    file_info: Dict[str, Any] = Field(default_factory=dict, description="File information")


class CallChainResponse(BaseResponse):
    """Response model for call chain analysis."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    start_function: str = Field(..., description="Starting function")
    end_function: str = Field(..., description="Target function")
    path_found: bool = Field(..., description="Whether a path was found")
    call_path: Optional[List[str]] = Field(None, description="Call path")
    path_length: int = Field(0, description="Path length")
    alternative_paths: List[List[str]] = Field(default_factory=list, description="Alternative paths")
    analysis_metadata: Dict[str, Any] = Field(default_factory=dict, description="Analysis metadata")


class BatchAnalysisResponse(BaseResponse):
    """Response model for batch analysis."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    results: List[AnalysisResponse] = Field(default_factory=list, description="Individual analysis results")
    summary: Dict[str, Any] = Field(default_factory=dict, description="Batch summary")
    failed_files: List[Dict[str, Any]] = Field(default_factory=list, description="Failed file analyses")
    export_path: Optional[str] = Field(None, description="Export file path")


class CodeViewResponse(BaseResponse):
    """Response model for code viewing."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    source_code: str = Field(..., description="Source code")
    file_path: str = Field(..., description="File path")
    start_line: int = Field(..., description="Start line number")
    end_line: int = Field(..., description="End line number")
    language: str = Field(..., description="Programming language")
    syntax_highlighted: bool = Field(False, description="Whether syntax highlighting was applied")
    context_included: bool = Field(False, description="Whether context lines are included")


class SessionResponse(BaseResponse):
    """Response model for session operations."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    session_id: str = Field(..., description="Session identifier")
    session_type: str = Field(..., description="Session type")
    configuration: Dict[str, Any] = Field(default_factory=dict, description="Session configuration")
    created_at: datetime = Field(..., description="Session creation time")
    expires_at: datetime = Field(..., description="Session expiration time")
    is_active: bool = Field(True, description="Whether session is active")


class DependencyAnalysisResponse(BaseResponse):
    """Response model for dependency analysis."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    file_path: str = Field(..., description="Analyzed file path")
    dependencies: List[Dict[str, Any]] = Field(default_factory=list, description="Dependencies")
    dependency_count: int = Field(0, description="Total dependency count")
    external_dependencies: List[Dict[str, Any]] = Field(default_factory=list, description="External dependencies")
    internal_dependencies: List[Dict[str, Any]] = Field(default_factory=list, description="Internal dependencies")
    dependency_tree: Dict[str, Any] = Field(default_factory=dict, description="Dependency tree structure")


class ValidationResponse(BaseResponse):
    """Response model for file validation."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    valid: bool = Field(..., description="Whether file is valid")
    file_path: str = Field(..., description="Validated file path")
    language: Optional[str] = Field(None, description="Detected/confirmed language")
    file_size: int = Field(0, description="File size in bytes")
    line_count: Optional[int] = Field(None, description="Number of lines")
    syntax_errors: List[Dict[str, Any]] = Field(default_factory=list, description="Syntax errors")
    warnings: List[str] = Field(default_factory=list, description="Validation warnings")


class SearchResponse(BaseResponse):
    """Response model for search operations."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    query: str = Field(..., description="Search query")
    results: List[Dict[str, Any]] = Field(default_factory=list, description="Search results")
    result_count: int = Field(0, description="Number of results")
    search_metadata: Dict[str, Any] = Field(default_factory=dict, description="Search metadata")


class ToolListResponse(BaseResponse):
    """Response model for tool listing."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    tools: List[Dict[str, Any]] = Field(default_factory=list, description="Available tools")
    tool_count: int = Field(0, description="Number of tools")
    languages: List[str] = Field(default_factory=list, description="Supported languages")
    tool_types: List[str] = Field(default_factory=list, description="Available tool types")


class HealthResponse(BaseResponse):
    """Response model for health checks."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    health_status: HealthStatus = Field(..., description="Overall health status")
    components: Dict[str, Dict[str, Any]] = Field(default_factory=dict, description="Component health")
    system_info: Dict[str, Any] = Field(default_factory=dict, description="System information")
    performance_metrics: Dict[str, Any] = Field(default_factory=dict, description="Performance metrics")
    uptime_seconds: float = Field(0.0, description="System uptime in seconds")
    
    class Config:
        schema_extra = {
            "example": {
                "status": "success",
                "health_status": "healthy",
                "components": {
                    "database": {"status": "healthy", "response_time": 0.05},
                    "cache": {"status": "healthy", "hit_rate": 0.85},
                    "mcp_instances": {"status": "healthy", "active_count": 4}
                },
                "system_info": {
                    "cpu_usage": 15.2,
                    "memory_usage": 45.8,
                    "disk_usage": 60.1
                },
                "uptime_seconds": 86400
            }
        }


class StatisticsResponse(BaseResponse):
    """Response model for statistics."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    statistics: Dict[str, Any] = Field(..., description="System statistics")
    period: str = Field("current", description="Statistics period")
    last_reset: Optional[datetime] = Field(None, description="Last statistics reset time")


class ExportResponse(BaseResponse):
    """Response model for export operations."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    export_format: str = Field(..., description="Export format")
    output_path: Optional[str] = Field(None, description="Output file path")
    content: Optional[str] = Field(None, description="Export content (for inline exports)")
    file_size: Optional[int] = Field(None, description="Export file size")
    export_metadata: Dict[str, Any] = Field(default_factory=dict, description="Export metadata")


class LoadBalancerResponse(BaseResponse):
    """Response model for load balancer information."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    strategy: str = Field(..., description="Load balancing strategy")
    total_instances: int = Field(0, description="Total MCP instances")
    healthy_instances: int = Field(0, description="Healthy MCP instances")
    total_requests: int = Field(0, description="Total requests processed")
    success_rate: float = Field(0.0, description="Success rate percentage")
    avg_response_time: float = Field(0.0, description="Average response time")
    instances: List[Dict[str, Any]] = Field(default_factory=list, description="Instance details")


class ConfigurationResponse(BaseResponse):
    """Response model for configuration operations."""
    status: ResponseStatus = ResponseStatus.SUCCESS
    configuration: Dict[str, Any] = Field(default_factory=dict, description="Configuration data")
    config_source: str = Field("unknown", description="Configuration source")
    last_modified: Optional[datetime] = Field(None, description="Last modification time")
    validation_status: str = Field("unknown", description="Validation status")